<template>
  <div class="form">
    <div v-if="tag==='input'" class="formItem">
      <label>{{title}}</label>
      <input target="writing" type="text" v-bind="$attrs" :class="validateForm.correct?'error':''" v-model="validateForm.value">
      <div :class="!validateForm.correct?'opecity':''" class="form-text">{{validateForm.message}}</div>
    </div>
    <div v-if="tag==='textarea'" class="formItem">
      <label>{{title}}</label>
      <textarea target="writing" type="text" rows="10" v-bind="$attrs" :class="validateForm.correct?'error':''" v-model="validateForm.value"></textarea>
      <div :class="!validateForm.correct?'opecity':''" class="form-text">{{validateForm.message}}</div>
    </div>
  </div>
</template>

<script lang="ts">
import {defineComponent,reactive,watch,PropType, ref,onMounted} from 'vue'
import { emitter } from './Jfrom.vue'
const emailReg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
interface RuleProp {
  type:'require'|'email'|'userlimit';
  message:string
}
export type RulesProp = RuleProp[]
export type TagType = 'input'|'textarea'
interface ValidateForm {
  value:string;
  correct:boolean;
  message:string
}
export default defineComponent({
  props:{
    rules: Array as PropType<RulesProp>,
    lable:{
      type:String,
      require:true
    },
    modelValue:String,
    tag:{
      type:String as PropType<TagType>, // 自定义的类型必须要使用 PropType 包裹起来才可使用
      default:'input'
    } 
  },
  inheritAttrs:false,  // 根元素不会继承写在组件标签上的一些属性 如 class type 等等
  setup(props,context){
    // console.log(context.attrs) // 这里存放了组件上面挂载的一系列的键值对  可以根据v-bind这个值动态的为标签绑定
    const validateForm = reactive<ValidateForm>({
      value:props.modelValue || '',
      correct:false,
      message:''
    })
    const title = ref(props.lable)
    const toValidate = ()=>{
      // v-model 可以使用 update:modelValue 事件 向外界传递出去
      context.emit('update:modelValue',validateForm.value)
      if(props.rules){
        // 数组的 every 方法会遍历数组的每一个元素 返回一个布尔类型，如果为 每一项为true则会返回true  只要有一个为false就会为false并停止遍历
        const allPased = props.rules.every(rule=>{
          let passed = true
          validateForm.message = rule.message
          switch (rule.type){
            case 'require':
              passed = (validateForm.value.trim() !== '')
              break
            case 'email':
              passed = emailReg.test(validateForm.value)
              break
            case 'userlimit':
              // passed = (validateForm.value.trim() !== '')
              passed = (validateForm.value.trim().length >= 6 && validateForm.value.trim().length <= 12)
              break
            default:
              break
          }
          return passed
        })
        validateForm.correct = !allPased
        return  allPased
      }
    }

    watch(()=>validateForm.value,toValidate)

    onMounted(()=>{
      emitter.emit('creat',toValidate)
    })

    return {
      validateForm,
      toValidate,
      title
    }
  }
})
</script>

<style lang="less" scoped>
.formItem{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  // margin-bottom: 5px;
  // label{
  //   margin: 5px 0;
  // }
  // height: 85px;
  >[target=writing]{
    width: 100%;
    min-height: 40px;
    padding: 0 10px;
    border-radius: 5px;
    margin-bottom: 2px;
    border: 1px solid #dcdfe6;
    &:hover{
      border-color: rgb(192, 196, 204);
    }
    &:focus{
      border-color: #409eff;
      outline: none;
    }
  }
  textarea{
    padding-top: 5px !important;
  }
  .form-text{
    color: #f56c6c;
    font-size: 12px;
    height: 16px;
  }
  .error{
    border-color: #f56c6c;
  }
  .opecity{
    opacity: 0;
  }
}
</style>